package asem.ast.sentencias;

import genc.GenC;
import alex.Token;
import asem.TablaSimbolos;
import asem.ast.expresiones.NodoExpresion;
import asem.excepciones.ExcepcionTipoRetorno;
import asem.tablaSimbolos.Constructor;
import asem.tablaSimbolos.Metodo;
import asem.tablaSimbolos.tipo.Tipo;
import asem.tablaSimbolos.tipo.TipoMetodo;
import asem.tablaSimbolos.tipo.TipoVoid;

public class NodoReturn extends NodoSentencia {
	protected Token retu;
	protected NodoExpresion expRetorno;

	public NodoReturn(Token r, NodoExpresion exp) {
		retu = r;
		expRetorno = exp;
	}

	public boolean chequeoSentencias(NodoBloque contenedor) {
		Constructor metodoActual = TablaSimbolos.tabla.metodoActual();

		if (!(metodoActual instanceof Metodo))
			throw new ExcepcionTipoRetorno(retu, metodoActual);

		TipoMetodo tipoMetodoActual = metodoActual.getRetorno();

		if (expRetorno == null) {
			if (!(tipoMetodoActual instanceof TipoVoid))
				throw new ExcepcionTipoRetorno(retu, metodoActual.getNombre());
		} else {
			Tipo tipoExpresionRetorno = (Tipo) expRetorno
					.chequeoSentencias(contenedor);
			if (tipoMetodoActual instanceof TipoVoid)
				throw new ExcepcionTipoRetorno(retu, metodoActual.getNombre(),
						metodoActual.getRetorno().toString());
			if (!((Tipo) tipoMetodoActual).compatible(tipoExpresionRetorno))
				throw new ExcepcionTipoRetorno(retu, metodoActual.getNombre(),
						metodoActual.getRetorno().toString());

			int corrimientos = metodoActual.getCantParametros() + 3;

			if (!((Metodo) metodoActual).esEstatico())
				corrimientos++; // corrimiento por el this

			GenC.gen.guardarResult(Integer.toString(corrimientos));
		}

		GenC.gen.terminaMetodo(metodoActual, contenedor.getCantVars());
		
		return true;
	}
}
